package com.triple.interviewexpert.blackfilter;

import com.alibaba.nacos.api.annotation.NacosInjected;
import com.alibaba.nacos.api.config.ConfigService;
import com.alibaba.nacos.api.config.listener.Listener;
import com.alibaba.nacos.api.exception.NacosException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.validation.constraints.NotNull;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 监听 Nacos 的配置
 */
@Slf4j
@Component
public class NacosListener implements InitializingBean {

    @NacosInjected
    private ConfigService configService;

    @Value("${nacos.config.data-id}")
    private String dataId;

    @Value("${nacos.config.group}")
    private String group;

    @Override
    public void afterPropertiesSet() throws Exception {
        log.info("nacos 监听器启动");
        String config;
        // 防止配置拉取失败
        try {
            config = configService.getConfigAndSignListener(dataId, group, 3000L, new Listener() {
                final ThreadFactory threadFactory = new ThreadFactory() {
                    private final AtomicInteger poolNumber = new AtomicInteger(1);
                    @Override
                    public Thread newThread(@NotNull Runnable r) {
                        Thread thread = new Thread(r);
                        thread.setName("refresh-ThreadPool" + poolNumber.getAndIncrement());
                        return thread;
                    }
                };
                final ExecutorService executorService = Executors.newFixedThreadPool(1, threadFactory);
                // 通过线程池异步处理黑名单变化的逻辑
                @Override
                public Executor getExecutor() {
                    return executorService;
                }

                // 重点: 监听后续黑名单变化
                @Override
                public void receiveConfigInfo(String configInfo) {
                    log.info("监听到配置信息变化：{}", configInfo);
                    BlackIpUtils.rebuildBlackIp(configInfo);
                }
            });
        } catch (NacosException e) {
            config = null;
        }
        // 启动时还未设置监听, 初始化黑名单
        log.info("config的内容为: {}", config);
        BlackIpUtils.rebuildBlackIp(config);
    }
}
